package rjp.mutation;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import rjp.map.SantaMap;
import rjp.solution.MapConnection;
import rjp.solution.Solution;

public class MoveSegmentMutation extends Mutation {
	
	private int segStart;
	private int segEnd;
	private int moveTo;
	
	public MoveSegmentMutation(int segStart, int segEnd, int moveTo, SantaMap map)
	{
		super(map);
		if(segStart>=segEnd || (moveTo>=segStart && moveTo<=segEnd) || segStart<1 || segEnd>map.size()-2 )
		{
			throw new IllegalArgumentException();
		}
		this.segStart=segStart;
		this.segEnd=segEnd;
		this.moveTo=moveTo;
	}
	

	@Override
	public Set<MapConnection> getAdditionalConnections(Solution solution) {
		Set<MapConnection> a=new HashSet<MapConnection>();
		if(moveTo>0)
		{
			a.add(new MapConnection(solution.getCityA(moveTo-1), solution.getCityA(segStart)));
		}
		if(moveTo<this.map.size())
		{
			a.add(new MapConnection(solution.getCityA(segEnd), solution.getCityA(moveTo)));
		}
		a.add(new MapConnection(solution.getCityA(segStart-1), solution.getCityA(segEnd+1)));
		return a;
	}

	@Override
	public Set<MapConnection> getObsoleteConnections(Solution solution) {
		Set<MapConnection> a=new HashSet<MapConnection>();
		if(moveTo>0 && moveTo<this.map.size())
		{
			a.add(new MapConnection(solution.getCityA(moveTo-1), solution.getCityA(moveTo)));
		}
		a.add(new MapConnection(solution.getCityA(segEnd), solution.getCityA(segEnd+1)));
		a.add(new MapConnection(solution.getCityA(segStart-1), solution.getCityA(segStart)));
		return a;
	}

	@Override
	public Solution mutate(Solution solution) {
		System.out.println(this.segStart+" "+this.segEnd+" "+this.moveTo);
		ArrayList<Integer> newA=new ArrayList<Integer>(map.size());
		if(this.moveTo<this.segStart)
		{
			newA.addAll(solution.getSubListA(0, this.moveTo));
			newA.addAll(solution.getSubListA(this.segStart, this.segEnd+1));
			newA.addAll(solution.getSubListA(this.moveTo, this.segStart));
			newA.addAll(solution.getSubListA(this.segEnd+1, this.map.size()));
		} else
		{
			newA.addAll(solution.getSubListA(0, this.segStart));
			newA.addAll(solution.getSubListA(this.segEnd+1, this.moveTo));
			newA.addAll(solution.getSubListA(this.segStart, this.segEnd+1));
			newA.addAll(solution.getSubListA(this.moveTo, this.map.size()));
		}
		solution.setPathA(newA);
		return solution;
	}
}
